/*
	skyeye_flash.c - skyeye general flash device file support functions
	Copyright (C) 2003 - 2005 Skyeye Develop Group
        for help please send mail to <skyeye-developer@lists.gro.clinux.org>
	
	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 
*/

/*
 * 09/22/2005 	initial version
 *			walimis <wlm@student.dlut.edu.cn>
 */

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#if __MINGW32__
#include <fcntl.h>
#include <sys/stat.h>
#endif

//#include "armdefs.h"
#include "skyeye_config.h"
#include "skyeye_device.h"

#include "skyeye_options.h"
#include "skyeye.h"
#include "skyeye_flash.h"

extern void flash_sst39lvf160_init(struct device_module_set *mod_set);

static int
do_flash_option (skyeye_option_t * this_option, int num_params,
		 const char *params[]);

/* initialize the flash module set.
 * If you want to add a new flash simulation, just add a "flash_*_init" function to it.
 * */
static void
flash_init (struct device_module_set *mod_set)
{
	flash_sst39lvf160_init (mod_set);
}
static int
flash_setup (struct device_desc *dev, void *option)
{
	struct flash_device *flash_dev;
	struct flash_option *flash_opt = (struct flash_option *) option;
	int ret = 0;

	flash_dev =
		(struct flash_device *) malloc (sizeof (struct flash_device));
	if (flash_dev == NULL)
		return 1;

	memset (flash_dev, 0, sizeof (struct flash_device));
	memcpy (&flash_dev->filebase[0], &flash_opt->filebase[0], MAX_STR_NAME);

	dev->dev = (void *) flash_dev;
	return ret;

}
static struct device_module_set flash_mod_set = {
	.name = "flash",
	.count = 0,
	.count_max = 0,
	.init = flash_init,
	.initialized = 0,
	.setup_module = flash_setup,
};

/* used by global device initialize function. 
 * */
void
flash_register ()
{
	if (register_device_module_set (&flash_mod_set))
		SKYEYE_ERR ("\"%s\" module set register error!\n",
			    flash_mod_set.name);
	if(register_option("flash", do_flash_option, "Nor flash chip related options.") != No_exp)
		SKYEYE_ERR("flash option register error!\n");
}

/* helper functions */
#ifdef __MINGW32__
	#include <io.h>
	#undef S_IREAD
	#undef S_IWRITE
	#undef O_CREAT
	#undef O_TRUNC
	#undef O_WRONLY
	#define S_IREAD				_S_IREAD
	#define S_IWRITE			_S_IWRITE
	#define O_CREAT				_O_CREAT
	#define O_TRUNC				_O_TRUNC
	#define O_WRONLY			(_O_WRONLY | _O_BINARY)
	#define open(file, flags, mode)		_open(file, flags, mode)
	#define close(fd)			_close(fd)
	#define write(fd, buf, count)		_write(fd, buf, count)
#else
	#include <sys/types.h>
	#include <sys/stat.h>
	#include <fcntl.h>
	#ifndef S_IREAD
		#define S_IREAD			S_IRUSR
	#endif
	#ifndef S_IWRITE
		#define S_IWRITE		S_IWUSR
	#endif
#endif


static int
do_flash_option (skyeye_option_t * this_option, int num_params,
		 const char *params[])
{
	char name[MAX_PARAM_NAME], value[MAX_PARAM_NAME];
	struct flash_option flash_opt;
	int i, fd;

	memset(&flash_opt, 0, sizeof(struct flash_option));

	for (i = 0; i < num_params; i++) {
		if (split_param (params[i], name, value) < 0)
			SKYEYE_ERR
				("Error: flash has wrong parameter \"%s\".\n",
				 name);

		if (!strncmp("filebase", name, strlen(name))) {
			memcpy(&flash_opt.filebase[0], value, strlen(value) + 1);
		}
	}
	SKYEYE_INFO ("flash: filebase %s\n",
		     flash_opt.filebase[0] == 0 ? "none" : flash_opt.filebase);

	setup_device_option (this_option->option_name, (void *) &flash_opt,
			     num_params, params);
	return 0;
}
